{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第9章 时序数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 一、时序的创建\n",
    "###  1. 四类时间变量\n",
    "#### 现在理解可能关于③和④有些困惑，后面会作出一些说明"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "名称 | 描述 | 元素类型 | 创建方式  \n",
    ":-|:-|:-|:-\n",
    "① Date times（时间点/时刻） | 描述特定日期或时间点 | Timestamp | to_datetime或date_range\n",
    "② Time spans（时间段/时期） | 由时间点定义的一段时期 | Period | Period或period_range\n",
    "③ Date offsets（相对时间差） | 一段时间的相对大小（与夏/冬令时无关） | DateOffset | DateOffset\n",
    "④ Time deltas（绝对时间差） | 一段时间的绝对大小（与夏/冬令时有关） | Timedelta | to_timedelta或timedelta_range"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 时间点的创建"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （a）to_datetime方法\n",
    "#### Pandas在时间点建立的输入格式规定上给了很大的自由度，下面的语句都能正确建立同一时间点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-01-01 00:00:00')"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime('2020.1.1')\n",
    "pd.to_datetime('2020 1.1')\n",
    "pd.to_datetime('2020 1 1')\n",
    "pd.to_datetime('2020 1-1')\n",
    "pd.to_datetime('2020-1 1')\n",
    "pd.to_datetime('2020-1-1')\n",
    "pd.to_datetime('2020/1/1')\n",
    "pd.to_datetime('1.1.2020')\n",
    "pd.to_datetime('1.1 2020')\n",
    "pd.to_datetime('1 1 2020')\n",
    "pd.to_datetime('1 1-2020')\n",
    "pd.to_datetime('1-1 2020')\n",
    "pd.to_datetime('1-1-2020')\n",
    "pd.to_datetime('1/1/2020')\n",
    "pd.to_datetime('20200101')\n",
    "pd.to_datetime('2020.0101')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 下面的语句都会报错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "#pd.to_datetime('2020\\\\1\\\\1')\n",
    "#pd.to_datetime('2020`1`1')\n",
    "#pd.to_datetime('2020.1 1')\n",
    "#pd.to_datetime('1 1.2020')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 此时可利用format参数强制匹配"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-01-01 00:00:00')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime('2020\\\\1\\\\1',format='%Y\\\\%m\\\\%d')\n",
    "pd.to_datetime('2020`1`1',format='%Y`%m`%d')\n",
    "pd.to_datetime('2020.1 1',format='%Y.%m %d')\n",
    "pd.to_datetime('1 1.2020',format='%d %m.%Y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 同时，使用列表可以将其转为时间点索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0\n",
       "2020-01-02    1\n",
       "dtype: int64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(range(2),index=pd.to_datetime(['2020/1/1','2020/1/2']))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pandas.core.indexes.datetimes.DatetimeIndex"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(pd.to_datetime(['2020/1/1','2020/1/2']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 对于DataFrame而言，如果列已经按照时间顺序排好，则利用to_datetime可自动转换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2020-01-01\n",
       "1   2020-01-02\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({'year': [2020, 2020],'month': [1, 1], 'day': [1, 2]})\n",
    "pd.to_datetime(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （b）时间精度与范围限制\n",
    "#### 事实上，Timestamp的精度远远不止day，可以最小到纳秒ns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-01-01 00:00:00.123456789')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime('2020/1/1 00:00:00.123456789')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 同时，它带来范围的代价就是只有大约584年的时间点是可用的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('1677-09-21 00:12:43.145225')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp.min"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2262-04-11 23:47:16.854775807')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp.max"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （c）date_range方法\n",
    "#### 一般来说，start/end/periods（时间点个数）/freq（间隔方法）是该方法最重要的参数，给定了其中的3个，剩下的一个就会被确定"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-01 00:00:00', '2020-01-05 12:00:00',\n",
       "               '2020-01-10 00:00:00'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start='2020/1/1',end='2020/1/10',periods=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',\n",
       "               '2020-01-05', '2020-01-06', '2020-01-07', '2020-01-08',\n",
       "               '2020-01-09', '2020-01-10'],\n",
       "              dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start='2020/1/1',end='2020/1/10',freq='D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03'], dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start='2020/1/1',periods=3,freq='D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03'], dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(end='2020/1/3',periods=3,freq='D')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 其中freq参数有许多选项，下面将常用部分罗列如下，更多选项可看[这里](https://pandas.pydata.org/docs/user_guide/timeseries.html#offset-aliases)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "符号 | D/B | W | M/Q/Y | BM/BQ/BY | MS/QS/YS | BMS/BQS/BYS | H | T | S\n",
    ":-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:\n",
    "描述 | 日/工作日 | 周 | 月末 | 月/季/年末日 | 月/季/年末工作日 | 月/季/年初日 | 月/季/年初工作日 | 小时 | 分钟 |秒"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-01 00:00:00', '2020-01-01 00:01:00',\n",
       "               '2020-01-01 00:02:00'],\n",
       "              dtype='datetime64[ns]', freq='T')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start='2020/1/1',periods=3,freq='T')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31'], dtype='datetime64[ns]', freq='M')"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start='2020/1/1',periods=3,freq='M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-01', '2021-01-01', '2022-01-03'], dtype='datetime64[ns]', freq='BAS-JAN')"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start='2020/1/1',periods=3,freq='BYS')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### bdate_range是一个类似与date_range的方法，特点在于可以在自带的工作日间隔设置上，再选择weekmask参数和holidays参数\n",
    "#### 它的freq中有一个特殊的'C'/'CBM'/'CBMS'选项，表示定制，需要联合weekmask参数和holidays参数使用\n",
    "#### 例如现在需要将工作日中的周一、周二、周五3天保留，并将部分holidays剔除"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-03', '2020-01-06', '2020-01-13', '2020-01-14'], dtype='datetime64[ns]', freq='C')"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weekmask = 'Mon Tue Fri'\n",
    "holidays = [pd.Timestamp('2020/1/%s'%i) for i in range(7,13)]\n",
    "#注意holidays\n",
    "pd.bdate_range(start='2020-1-1',end='2020-1-15',freq='C',weekmask=weekmask,holidays=holidays)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. DateOffset对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （a）DataOffset与Timedelta的区别\n",
    "#### Timedelta绝对时间差的特点指无论是冬令时还是夏令时，增减1day都只计算24小时\n",
    "#### DataOffset相对时间差指，无论一天是23\\24\\25小时，增减1day都与当天相同的时间保持一致\n",
    "#### 例如，英国当地时间 2020年03月29日，01:00:00 时钟向前调整 1 小时 变为 2020年03月29日，02:00:00，开始夏令时"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-03-30 02:00:00+0300', tz='Europe/Helsinki')"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts = pd.Timestamp('2020-3-29 01:00:00', tz='Europe/Helsinki')\n",
    "ts + pd.Timedelta(days=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-03-30 01:00:00+0300', tz='Europe/Helsinki')"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts + pd.DateOffset(days=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 这似乎有些令人头大，但只要把tz（time zone）去除就可以不用管它了，两者保持一致，除非要使用到时区变换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-03-30 01:00:00')"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts = pd.Timestamp('2020-3-29 01:00:00')\n",
    "ts + pd.Timedelta(days=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-03-30 01:00:00')"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts + pd.DateOffset(days=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （b）增减一段时间\n",
    "#### DateOffset的可选参数包括years/months/weeks/days/hours/minutes/seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2019-12-18 00:20:00')"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('2020-01-01') + pd.DateOffset(minutes=20) - pd.DateOffset(weeks=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （c）各类常用offset对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "freq | D/B | W | (B)M/(B)Q/(B)Y | (B)MS/(B)QS/(B)YS | H | T | S | C |\n",
    ":-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:\n",
    "offset | DateOffset/BDay | Week | (B)MonthEnd/(B)QuarterEnd/(B)YearEnd | (B)MonthBegin/(B)QuarterBegin/(B)YearBegin | Hour | Minute | Second | CDay(定制工作日)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-01-15 00:00:00')"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('2020-01-01') + pd.offsets.Week(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2020-03-02 00:00:00')"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('2020-01-01') + pd.offsets.BQuarterBegin(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （d）序列的offset操作\n",
    "#### 利用apply函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2023-01-02\n",
       "1   2024-01-01\n",
       "2   2025-01-01\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(pd.offsets.BYearBegin(3).apply(i) for i in pd.date_range('20200101',periods=3,freq='Y'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 直接使用对象加减"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2023-01-02', '2024-01-01', '2025-01-01'], dtype='datetime64[ns]', freq='A-DEC')"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range('20200101',periods=3,freq='Y') + pd.offsets.BYearBegin(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 定制offset，可以指定weekmask和holidays参数（思考为什么三个都是一个值）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2020-01-15\n",
       "1   2020-01-15\n",
       "2   2020-01-15\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(pd.offsets.CDay(3,weekmask='Wed Fri',holidays='2020010').apply(i)\n",
    "                                  for i in pd.date_range('20200105',periods=3,freq='D'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 二、时序的索引及属性\n",
    "### 1. 索引切片\n",
    "#### 这一部分几乎与第二章的规则完全一致"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-05   -0.275349\n",
       "2020-01-12    2.359218\n",
       "2020-01-19   -0.447633\n",
       "2020-01-26   -0.479830\n",
       "2020-02-02    0.517587\n",
       "Freq: W-SUN, dtype: float64"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng = pd.date_range('2020','2021', freq='W')\n",
    "ts = pd.Series(np.random.randn(len(rng)), index=rng)\n",
    "ts.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.47982974619679947"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['2020-01-26']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 合法字符自动转换为时间点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-26   -0.479830\n",
       "2020-02-02    0.517587\n",
       "2020-02-09   -0.575879\n",
       "2020-02-16    0.952187\n",
       "2020-02-23    0.554098\n",
       "Freq: W-SUN, dtype: float64"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['2020-01-26':'20200726'].head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 子集索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-07-05   -0.088912\n",
       "2020-07-12    0.153852\n",
       "2020-07-19    1.670324\n",
       "2020-07-26    0.568214\n",
       "Freq: W-SUN, dtype: float64"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['2020-7'].head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 支持混合形态索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-05   -0.275349\n",
       "2020-01-12    2.359218\n",
       "2020-01-19   -0.447633\n",
       "2020-01-26   -0.479830\n",
       "2020-02-02    0.517587\n",
       "Freq: W-SUN, dtype: float64"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['2011-1':'20200726'].head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 时间点的属性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 采用dt对象可以轻松获得关于时间的信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1\n",
       "1    2\n",
       "2    3\n",
       "3    4\n",
       "4    5\n",
       "dtype: int64"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(ts.index).dt.week.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     5\n",
       "1    12\n",
       "2    19\n",
       "3    26\n",
       "4     2\n",
       "dtype: int64"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(ts.index).dt.day.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 利用strftime可重新修改时间格式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    2020-间隔1-01-间隔2-05\n",
       "1    2020-间隔1-01-间隔2-12\n",
       "2    2020-间隔1-01-间隔2-19\n",
       "3    2020-间隔1-01-间隔2-26\n",
       "4    2020-间隔1-02-间隔2-02\n",
       "dtype: object"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(ts.index).dt.strftime('%Y-间隔1-%m-间隔2-%d').head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 对于datetime对象可以直接通过属性获取信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64Index([ 1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,  3,  4,  4,  4,  4,\n",
       "             5,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,\n",
       "             8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12,\n",
       "            12],\n",
       "           dtype='int64')"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range('2020','2021', freq='W').month"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64Index([6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n",
       "            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n",
       "            6, 6, 6, 6, 6, 6, 6, 6],\n",
       "           dtype='int64')"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range('2020','2021', freq='W').weekday"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 三、重采样"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 所谓重采样，就是指resample函数，它可以看做时序版本的groupby函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. resample对象的基本操作\n",
    "#### 采样频率一般设置为上面提到的offset字符"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_r = pd.DataFrame(np.random.randn(1000, 3),index=pd.date_range('1/1/2020', freq='S', periods=1000),\n",
    "                  columns=['A', 'B', 'C'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.resample.DatetimeIndexResampler object at 0x7ff73ebafc10>"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = df_r.resample('3min')\n",
    "r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:00:00</th>\n",
       "      <td>-8.772685</td>\n",
       "      <td>-27.074716</td>\n",
       "      <td>2.134617</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:03:00</th>\n",
       "      <td>3.822484</td>\n",
       "      <td>8.912459</td>\n",
       "      <td>-15.448955</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:06:00</th>\n",
       "      <td>2.744722</td>\n",
       "      <td>-8.055139</td>\n",
       "      <td>-11.364361</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:09:00</th>\n",
       "      <td>4.655620</td>\n",
       "      <td>-11.524496</td>\n",
       "      <td>-10.536002</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:12:00</th>\n",
       "      <td>-10.546811</td>\n",
       "      <td>5.063887</td>\n",
       "      <td>11.776490</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:15:00</th>\n",
       "      <td>8.795150</td>\n",
       "      <td>-12.828809</td>\n",
       "      <td>-8.393950</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                             A          B          C\n",
       "2020-01-01 00:00:00  -8.772685 -27.074716   2.134617\n",
       "2020-01-01 00:03:00   3.822484   8.912459 -15.448955\n",
       "2020-01-01 00:06:00   2.744722  -8.055139 -11.364361\n",
       "2020-01-01 00:09:00   4.655620 -11.524496 -10.536002\n",
       "2020-01-01 00:12:00 -10.546811   5.063887  11.776490\n",
       "2020-01-01 00:15:00   8.795150 -12.828809  -8.393950"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-01</th>\n",
       "      <td>5.278470</td>\n",
       "      <td>1.688588</td>\n",
       "      <td>5.904806</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-02-03</th>\n",
       "      <td>-3.581797</td>\n",
       "      <td>7.515267</td>\n",
       "      <td>0.205308</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-03-02</th>\n",
       "      <td>-5.021605</td>\n",
       "      <td>-4.441066</td>\n",
       "      <td>5.433917</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-04-01</th>\n",
       "      <td>0.671702</td>\n",
       "      <td>3.840042</td>\n",
       "      <td>4.922487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-05-01</th>\n",
       "      <td>4.613352</td>\n",
       "      <td>9.702408</td>\n",
       "      <td>-4.928112</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-06-01</th>\n",
       "      <td>-0.598191</td>\n",
       "      <td>7.387416</td>\n",
       "      <td>8.716921</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-07-01</th>\n",
       "      <td>-0.327200</td>\n",
       "      <td>-1.577507</td>\n",
       "      <td>-3.956079</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   A         B         C\n",
       "2020-01-01  5.278470  1.688588  5.904806\n",
       "2020-02-03 -3.581797  7.515267  0.205308\n",
       "2020-03-02 -5.021605 -4.441066  5.433917\n",
       "2020-04-01  0.671702  3.840042  4.922487\n",
       "2020-05-01  4.613352  9.702408 -4.928112\n",
       "2020-06-01 -0.598191  7.387416  8.716921\n",
       "2020-07-01 -0.327200 -1.577507 -3.956079"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_r2 = pd.DataFrame(np.random.randn(200, 3),index=pd.date_range('1/1/2020', freq='D', periods=200),\n",
    "                  columns=['A', 'B', 'C'])\n",
    "r = df_r2.resample('CBMS')\n",
    "r.sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 采样聚合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "r = df_r.resample('3T')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01 00:00:00   -0.048737\n",
       "2020-01-01 00:03:00    0.021236\n",
       "2020-01-01 00:06:00    0.015248\n",
       "2020-01-01 00:09:00    0.025865\n",
       "2020-01-01 00:12:00   -0.058593\n",
       "2020-01-01 00:15:00    0.087952\n",
       "Freq: 3T, Name: A, dtype: float64"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r['A'].mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sum</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:00:00</th>\n",
       "      <td>-8.772685</td>\n",
       "      <td>-0.048737</td>\n",
       "      <td>0.939954</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:03:00</th>\n",
       "      <td>3.822484</td>\n",
       "      <td>0.021236</td>\n",
       "      <td>1.004048</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:06:00</th>\n",
       "      <td>2.744722</td>\n",
       "      <td>0.015248</td>\n",
       "      <td>1.018865</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:09:00</th>\n",
       "      <td>4.655620</td>\n",
       "      <td>0.025865</td>\n",
       "      <td>1.020881</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:12:00</th>\n",
       "      <td>-10.546811</td>\n",
       "      <td>-0.058593</td>\n",
       "      <td>0.954328</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:15:00</th>\n",
       "      <td>8.795150</td>\n",
       "      <td>0.087952</td>\n",
       "      <td>1.199379</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                           sum      mean       std\n",
       "2020-01-01 00:00:00  -8.772685 -0.048737  0.939954\n",
       "2020-01-01 00:03:00   3.822484  0.021236  1.004048\n",
       "2020-01-01 00:06:00   2.744722  0.015248  1.018865\n",
       "2020-01-01 00:09:00   4.655620  0.025865  1.020881\n",
       "2020-01-01 00:12:00 -10.546811 -0.058593  0.954328\n",
       "2020-01-01 00:15:00   8.795150  0.087952  1.199379"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r['A'].agg([np.sum, np.mean, np.std])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 类似地，可以使用函数/lambda表达式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:00:00</th>\n",
       "      <td>-8.772685</td>\n",
       "      <td>4.950006</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:03:00</th>\n",
       "      <td>3.822484</td>\n",
       "      <td>5.711679</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:06:00</th>\n",
       "      <td>2.744722</td>\n",
       "      <td>6.923072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:09:00</th>\n",
       "      <td>4.655620</td>\n",
       "      <td>6.370589</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:12:00</th>\n",
       "      <td>-10.546811</td>\n",
       "      <td>4.544878</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-01 00:15:00</th>\n",
       "      <td>8.795150</td>\n",
       "      <td>5.244546</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                             A         B\n",
       "2020-01-01 00:00:00  -8.772685  4.950006\n",
       "2020-01-01 00:03:00   3.822484  5.711679\n",
       "2020-01-01 00:06:00   2.744722  6.923072\n",
       "2020-01-01 00:09:00   4.655620  6.370589\n",
       "2020-01-01 00:12:00 -10.546811  4.544878\n",
       "2020-01-01 00:15:00   8.795150  5.244546"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.agg({'A': np.sum,'B': lambda x: max(x)-min(x)})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 采样组的迭代\n",
    "#### 采样组的迭代和groupby迭代完全类似，对于每一个组都可以分别做相应操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Group:  2020-01-01 00:00:00\n",
      "---------------------------\n",
      "2020-01-01 00:00:00    0\n",
      "2020-01-01 00:30:00    1\n",
      "2020-01-01 00:31:00    2\n",
      "dtype: int64\n",
      "\n",
      "Group:  2020-01-01 01:00:00\n",
      "---------------------------\n",
      "2020-01-01 01:00:00    3\n",
      "dtype: int64\n",
      "\n",
      "Group:  2020-01-01 02:00:00\n",
      "---------------------------\n",
      "Series([], dtype: int64)\n",
      "\n",
      "Group:  2020-01-01 03:00:00\n",
      "---------------------------\n",
      "2020-01-01 03:00:00    4\n",
      "2020-01-01 03:05:00    5\n",
      "dtype: int64\n",
      "\n"
     ]
    }
   ],
   "source": [
    "small = pd.Series(range(6),index=pd.to_datetime(['2020-01-01 00:00:00', '2020-01-01 00:30:00'\n",
    "                                                 , '2020-01-01 00:31:00','2020-01-01 01:00:00'\n",
    "                                                 ,'2020-01-01 03:00:00','2020-01-01 03:05:00']))\n",
    "resampled = small.resample('H')\n",
    "for name, group in resampled:\n",
    "    print(\"Group: \", name)\n",
    "    print(\"-\" * 27)\n",
    "    print(group, end=\"\\n\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 四、窗口函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 下面主要介绍pandas中两类主要的窗口(window)函数:rolling/expanding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.185221\n",
       "2020-01-03   -0.646472\n",
       "2020-01-04   -1.430293\n",
       "2020-01-05   -0.956094\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2020', periods=1000))\n",
    "s.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Rolling\n",
    "#### （a）常用聚合\n",
    "#### 所谓rolling方法，就是规定一个窗口，它和groupby对象一样，本身不会进行操作，需要配合聚合函数才能计算结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Rolling [window=50,center=False,axis=0]"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling(window=50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01         NaN\n",
       "2020-01-02         NaN\n",
       "2020-01-03         NaN\n",
       "2020-01-04         NaN\n",
       "2020-01-05         NaN\n",
       "                ...   \n",
       "2022-09-22    0.160743\n",
       "2022-09-23    0.136296\n",
       "2022-09-24    0.147523\n",
       "2022-09-25    0.133087\n",
       "2022-09-26    0.130841\n",
       "Freq: D, Length: 1000, dtype: float64"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling(window=50).mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### min_periods参数是指需要的非缺失数据点数量阀值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01         NaN\n",
       "2020-01-02         NaN\n",
       "2020-01-03   -0.051759\n",
       "2020-01-04   -0.396392\n",
       "2020-01-05   -0.508333\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling(window=50,min_periods=3).mean().head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### count/sum/mean/median/min/max/std/var/skew/kurt/quantile/cov/corr都是常用的聚合函数\n",
    "#### （b）rolling的apply聚合\n",
    "#### 使用apply聚合时，只需记住传入的是window大小的Series，输出的必须是标量即可，比如如下计算变异系数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01          NaN\n",
       "2020-01-02          NaN\n",
       "2020-01-03   -10.018809\n",
       "2020-01-04    -2.040720\n",
       "2020-01-05    -1.463460\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling(window=50,min_periods=3).apply(lambda x:x.std()/x.mean()).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （c）基于时间的rolling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.245598\n",
       "2020-01-03   -0.051759\n",
       "2020-01-04   -0.396392\n",
       "2020-01-05   -0.508333\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling('15D').mean().head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 可选closed='right'（默认）\\'left'\\'both'\\'neither'参数，决定端点的包含情况"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.491195\n",
       "2020-01-03   -0.155277\n",
       "2020-01-04   -1.585570\n",
       "2020-01-05   -2.541664\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling('15D', closed='right').sum().head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Expanding"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （a）expanding函数\n",
    "#### 普通的expanding函数等价与rolling(window=len(s),min_periods=1)，是对序列的累计计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.491195\n",
       "2020-01-03   -0.155277\n",
       "2020-01-04   -1.585570\n",
       "2020-01-05   -2.541664\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.rolling(window=len(s),min_periods=1).sum().head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.491195\n",
       "2020-01-03   -0.155277\n",
       "2020-01-04   -1.585570\n",
       "2020-01-05   -2.541664\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.expanding().sum().head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### apply方法也是同样可用的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.491195\n",
       "2020-01-03   -0.155277\n",
       "2020-01-04   -1.585570\n",
       "2020-01-05   -2.541664\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.expanding().apply(lambda x:sum(x)).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### （b）几个特别的Expanding类型函数\n",
    "#### cumsum/cumprod/cummax/cummin都是特殊expanding累计计算方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.491195\n",
       "2020-01-03   -0.155277\n",
       "2020-01-04   -1.585570\n",
       "2020-01-05   -2.541664\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.cumsum().head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01    0.305974\n",
       "2020-01-02    0.491195\n",
       "2020-01-03   -0.155277\n",
       "2020-01-04   -1.585570\n",
       "2020-01-05   -2.541664\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.cumsum().head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### shift/diff/pct_change都是涉及到了元素关系\n",
    "#### ①shift是指序列索引不变，但值向后移动\n",
    "#### ②diff是指前后元素的差，period参数表示间隔，默认为1，并且可以为负\n",
    "#### ③pct_change是值前后元素的变化百分比，period参数与diff类似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01         NaN\n",
       "2020-01-02         NaN\n",
       "2020-01-03    0.305974\n",
       "2020-01-04    0.185221\n",
       "2020-01-05   -0.646472\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.shift(2).head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01         NaN\n",
       "2020-01-02         NaN\n",
       "2020-01-03         NaN\n",
       "2020-01-04   -1.736267\n",
       "2020-01-05   -1.141316\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.diff(3).head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2020-01-01         NaN\n",
       "2020-01-02         NaN\n",
       "2020-01-03         NaN\n",
       "2020-01-04   -5.674559\n",
       "2020-01-05   -6.161897\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.pct_change(3).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 五、问题与练习\n",
    "#### 【问题一】 如何对date_range进行批量加帧操作或对某一时间段加大时间戳密度？\n",
    "#### 【问题二】 如何批量增加TimeStamp的精度？\n",
    "#### 【问题三】 对于超出处理时间的时间点，是否真的完全没有处理方法？\n",
    "#### 【问题四】 给定一组非连续的日期，怎么快速找出位于其最大日期和最小日期之间，且没有出现在该组日期中的日期？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 【练习一】 现有一份关于某超市牛奶销售额的时间序列数据，请完成下列问题：\n",
    "#### （a）销售额出现最大值的是星期几？（提示：利用dayofweek函数）\n",
    "#### （b）计算除去春节、国庆、五一节假日的月度销售总额\n",
    "#### （c）按季度计算周末（周六和周日）的销量总额\n",
    "#### （d）从最后一天开始算起，跳过周六和周一，以5天为一个时间单位向前计算销售总和\n",
    "#### （e）假设现在发现数据有误，所有同一周里的周一与周五的销售额记录颠倒了，请计算2018年中每月第一个周一的销售额（如果该周没有周一或周五的记录就保持不动）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>日期</th>\n",
       "      <th>销售额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2017/2/17</td>\n",
       "      <td>2154</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2017/2/18</td>\n",
       "      <td>2095</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2017/2/19</td>\n",
       "      <td>3459</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2017/2/20</td>\n",
       "      <td>2198</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2017/2/21</td>\n",
       "      <td>2413</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          日期   销售额\n",
       "0  2017/2/17  2154\n",
       "1  2017/2/18  2095\n",
       "2  2017/2/19  3459\n",
       "3  2017/2/20  2198\n",
       "4  2017/2/21  2413"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.read_csv('data/time_series_one.csv').head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 【练习二】 继续使用上一题的数据，请完成下列问题：\n",
    "#### （a）以50天为窗口计算滑窗均值和滑窗最大值（min_periods设为1）\n",
    "#### （b）现在有如下规则：若当天销售额超过向前5天的均值，则记为1，否则记为0，请给出2018年相应的计算结果\n",
    "#### （c）将(c)中的“向前5天”改为“向前非周末5天”，请再次计算结果"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
